<template>
  <div class="header van-hairline--top-bottom">
    <div class="header-menus" v-show="!easySearchChunk">
      <van-tabs v-model="tabActive" color="#1989fa" :swipe-threshold="swipeThreshold" ref="tabs">
        <van-tab 
          v-for="(menu,index) in menus"
          :name="menu.title" 
          :title="menu.title"
          :key="index"
          :url="menu.isOpenNewPage?menu.path:null"
          :to="menu.isOpenNewPage?null:menu.router"
          >
        </van-tab>
      </van-tabs>
    </div>
    <div class="header-icons" v-show="!easySearchChunk">
      <van-icon name="search" size="20" class="icon-wrap" color="#8A8A8A" v-if="curMenu.type === 'grid' && easySearchMetas.length" @click="easySearchChunk = true"/>
      <van-icon name="filter-o" size="20" class="icon-wrap" color="#8A8A8A" v-if="curMenu.type === 'grid'" @click="showAdvanceSearch"/>
    </div>
    <!-- 快速搜索 -->
    <van-search 
      v-show="easySearchChunk"
      v-model.trim="easySearchVal"
      :placeholder="easySearchPlaceholder"
      show-action
      clearable
      @search="onEasySearch"
      @input="easySearchHelper = true"
      @blur="easySearchHelper = false"
      style="flex: 1"
    >
      <span slot="action" style="color: #1989fa;" @click="onEasySearchCancel">取消</span>
    </van-search>
    <van-popup 
      v-model="easySearchHelper" 
      get-container="body" 
      position="top" 
      :style="{ 'width': '100%','max-height': 'calc(100% - 54px)','top': '54px'}" 
      :overlay-style="{ 'top': '54px', 'height': 'calc(100% - 54px)'}">
      <div class="easy-search-chunk">
        <section class="easy-search-content">
          <div class="van-cell easy-search-meta" v-for="(item, index) in easySearchMetas" :key="index" @click="onceEasySearch(item)">
            搜索 <span class="easy-search-caption">{{item.caption || item.name}}</span> : <span class="easy-search-query">{{easySearchVal}}</span>
          </div>
        </section>
      </div>
    </van-popup>
    <!-- 高级搜索 -->
    <van-popup v-model="advanceSearchChunk" get-container="body" position="right" @click-overlay="onAdvanceSearchCancel" :style="{ width: '80%',height: '100%' }">
      <div class="advance-search-container">
        <!-- 流程状态栏 -->
        <div class="filter-item van-hairline--bottom" v-if="procStatuses.length">
          <p>{{procStatuses.caption || '流程状态'}}</p>
          <div class="filter-item-content">
            <div class="btn-default btn-default-fixed van-ellipsis" 
              v-for="status in procStatuses" 
              :key="status.id" 
              :class="[{'active':status.active}]"
              @click="statusHandle(status)">
              <span>{{status.name}}</span>
            </div>
          </div>
        </div>
        <!-- 类别栏 -->
        <div class="filter-item van-hairline--bottom" v-if="categories.length">
          <p>{{categoryMeta.caption || categoryMeta.name || "类别"}}</p>
          <div class="filter-item-content">
            <div class="btn-default van-ellipsis" 
              v-for="item in categories" 
              :key="item.id"
              :class="[{'active':item.active}]"
              @click="categoryHandle(item)"
              style="margin-right: 8px">
              <span>{{item.name}}</span>
            </div>
          </div>
        </div>
        <div class="filter-footer">
          <van-button 
            type="info" 
            size="small" 
            @click="onAdvanceSearch" 
            :disabled="!this.procStatuses.length && !this.categories.length"
          >确定</van-button>
        </div>
      </div>
    </van-popup>
  </div>
</template>

<script>

/*!
 *  这是一个移动menus组件，结合快速搜索与高级搜索，对标pc功能
 *  内容约定说明（确认人-- 王志伟 2020/1/10）：
 *    1. 两种搜索模式下，<取消> 操作一律做初始化处理，即清除所有因人工操作而出现的数据
 *    2. 高级搜索中“状态”栏显示的是searchMeta中的 <流程状态>，判断依据是___procStatus,没有不显示该模块，名称固定
 *    3. 高级搜索中“类别”栏显示的是searchMeta中的是属性符合 xtype==="select"&& search.xtype === "multi-select2" 的第一条数据，没有不显示该模块，名称获取
 *    4. “状态”、“类别”栏皆为单选
 *  高级搜索“状态”、“类别”栏样式约定说明（确认人-- 刘伟峰 2020/1/10）：
 *    1. 状态栏显示固定宽度，每行显示3个状态信息
 *    2. 类别栏显示自由宽度，最大为一行宽
 */
import { request } from 'utils/http'
import { getSearchCondition } from 'utils/dataType'
import MbList from '../mb-list/index.vue'

export default {
  name: 'mb-header',
  components:{
    [MbList.name]: MbList
  },
  data () {
    return {
      tabActive: this.active,
      curMenu: {},
      swipeThreshold: 4,
      easySearchChunk: false,
      easySearchHelper: false,
      easySearchPlaceholder: '请输入',
      easySearchMetas: [],
      advanceSearchChunk: false,
      easySearchVal: null,
      procStatuses: [],
      categoryMeta: {},
      categories: [],
      advanceResult: []
    }
  },
  props: {
    menus: {
      type: Array,
      default: () => []
    },
    advanceSearchMeta: {
      type: Array,
      default: () => []
    },
    signs: Object,
    time: [String, Number],
    active: [String, Number]
  },
  watch: {
    advanceSearchMeta: function(newArr){
      const _this = this;
      this.easySearchMetas = [];
      this.easySearchPlaceholder = "请输入";
      newArr.forEach((meta) => {
        if(!meta.hidden && (!meta.xtype || meta.xtype == 'text')) {
          _this.easySearchMetas.push(meta);
          _this.easySearchPlaceholder += (meta.caption || meta.name) + '/'
        }
      })
      if(/\/$/.test(this.easySearchPlaceholder)) this.easySearchPlaceholder = this.easySearchPlaceholder.slice(0, -1);
      this.$nextTick(function() {
        this.$refs.tabs.resize();
      })
    },
    tabActive: function(val){
      this.curMenu = this.menus.filter((menu) => {return menu.title === val})[0];
    }
  },
  computed: {
    // TODO: do somthing...
  },
  beforeRouteEnter (to, from, next) {
    next()
  },
  beforeRouteUpdate (to, from, next) {
    next()
  },
  methods: {
    onEasySearch(val) {
      let easysearchResult = [];
      if(val){
        let searchParamsArr = [];
        this.easySearchMetas.forEach((meta) => {
          let obj = {};
          obj.name = meta.name;
          if(meta.caption) obj.caption = meta.caption;
          obj.linkOpt = "OR";
          obj.value = val;
          searchParamsArr.push(obj)
        })
        easysearchResult = this._getQuerySetting(searchParamsArr);     
      }
      this.$emit("easy-search", easysearchResult);
    },
    onceEasySearch(item) {
      let easysearchResult = [];
      if(this.easySearchVal) {
        let searchParamsArr = [];
        let obj = {};
        obj.name = item.name;
        if(item.caption) obj.caption = item.caption;
        obj.linkOpt = "AND";
        obj.value = this.easySearchVal;
        searchParamsArr.push(obj);
        easysearchResult = this._getQuerySetting(searchParamsArr);
      }
      this.$emit("easy-search", easysearchResult);
      this.easySearchHelper = false;
    },
    _getQuerySetting(arr) {
      let hashArr = new Array;
      this.easySearchMetas.forEach((meta) => {
        hashArr[meta.name] = meta;
      })
      arr = arr.reduce((ret, element) => {
        // 时间范围特殊处理
        if (hashArr[element.name]["dataType"] === 'Timestamp') {
          const [start, end] = element.value.split(',')
          ret.push([
            { ...element, value: start, builder: 'moreEqual'},
            { ...element, value: end, builder: 'lessEqual'},
          ])
        } else {
          element.builder = 'include';
          if (hashArr[element.name]) {
            element.builder = getSearchCondition(hashArr[element.name]["dataType"])
          }
          ret.push(element)
        }
        return ret
      }, []);
      return arr
    },
    onEasySearchCancel() {
      this.easySearchChunk = false;
      this.easySearchVal = null;
      this.$emit("easy-search", []);
    },
    showAdvanceSearch() {
      const _this = this;
      if(!this.advanceSearchMeta.length) {
        this.$notify({ type: 'warning', message: '无有效的搜索条件！' });
        return
      }
      this.advanceSearchChunk = true;
      let procStatus = this.advanceSearchMeta.filter((meta) => meta.name === "___procStatus") || [];
      if(procStatus.length) {
        procStatus =  procStatus[0];
        let tag = procStatus.url.slice(procStatus.url.lastIndexOf('/') + 1, procStatus.url.lastIndexOf('.'));
        request(procStatus.url, {
          query:{
            time: this.time,
            sign: this.signs[tag]
          }
        }).then(res => {
          if(res.code !== "0") {
            this.$notify({ type: 'danger', message: '获取流程状态失败！' });
            return
          }
          if(res.datas && res.datas && res.datas.code && res.datas.code.rows) _this.procStatuses = res.datas.code.rows;
        })
      }
      this.categoryMeta = this.advanceSearchMeta.filter((meta) => meta.xtype === "select" && meta["search.xtype"] === "multi-select2") || [];
      if(this.categoryMeta.length){
        this.categoryMeta = this.categoryMeta[0];
        let tag = this.categoryMeta.url.slice(this.categoryMeta.url.lastIndexOf('/') + 1, this.categoryMeta.url.lastIndexOf('.'));
        request(this.categoryMeta.url, {
          query:{
            time: this.time,
            sign: this.signs[tag]
          }
        }).then(res => {
          if(res.code !== "0") {
            this.$notify({ type: 'danger', message: "获取类型(" + _this.categoryMeta.name +")失败！" });
            return
          }
          if(res.datas && res.datas && res.datas.code && res.datas.code.rows) _this.categories = res.datas.code.rows;
        })
      }

    },
    onAdvanceSearch() {
      this.advanceResult = [];
      this.procStatuses.forEach(item => {
        if(item.active) {
          this.advanceResult.push({
            "name":"___procStatus",
            "caption":"流程状态",
            "linkOpt":"AND",
            "value": item.id,
            "value_display": item.name,
            "builder":"equal"
          })
        }
      });
      this.categories.forEach(item => {
        if(item.active) {
          this.advanceResult.push({
            "name":"性别",
            "caption":"性别",
            "linkOpt":"AND",
            "value": item.id,
            "value_display": item.name,
            "builder":"equal"
          })
        }
      });
      if(this.advanceResult.length) {
        this.procStatuses = [];
        this.categories = []; 
      }
      this.advanceSearchChunk = false;
      this.$emit("advance-search", this.advanceResult);
    },
    onAdvanceSearchCancel() {
      // TODO： 同onEasySearchCancel
    },
    statusHandle(status) {
      this.procStatuses = this.procStatuses.map((item) => {
        item.active = status.id === item.id ? !status.active : false;
        return item
      })
    },
    categoryHandle(category) {
      this.categories = this.categories.map((item) => {
        item.active = category.id === item.id ? !category.active : false;
        return item
      })
    }
  },
  mounted() {
    if(this.advanceSearchMeta.length) {
      this.advanceSearchMeta.forEach((meta) => {
        if(!meta.hidden && (!meta.xtype || meta.xtype == 'text')) {
          this.easySearchMetas.push(meta);
          this.easySearchPlaceholder += (meta.caption || meta.name) + '/'
        }
      })
      if(/\/$/.test(this.easySearchPlaceholder)) this.easySearchPlaceholder = this.easySearchPlaceholder.slice(0, -1);
    }
    this.curMenu = this.menus.filter((menu) => {return menu.title ===this.active})[0]
  },
  created() {
    // TODO: do somthing...
  },
}
</script>

<style>
  .header {
    display: flex;
  }
  .header-menus {
    flex: 1;
  }
  .header-icons {
    padding: 0 5px;
  }
  .icon-wrap {
    padding: 12px 2px 12px 3px;
  }
  .easy-search-chunk,.advance-search-container {
    width: 100%;
    height: 100%;
    background-color: #fff;
  }
  .easy-search-meta {
    font-size: 12px;
  }
  .easy-search-caption, .easy-search-query {
    margin-left: 4px;
  }
  .advance-search-container {
    padding: 0 10px;
  }
  .filter-item-content{
    margin-left: -4px;
    margin-right: -4px
  }
  .filter-item p{
    margin: 12px 0;
  }
  .filter-item-content::after {
    display: table;
    clear: both;
    content: "";
  }
  .btn-default {
    float: left;
    height: 44px;
    line-height: 44px;
    text-align: center;
    color: #323233;
    padding: 0 10px;
    font-size: 14px;
    max-width: 100%;
    margin-bottom: 8px; 
    background-color: rgba(0, 0, 0,.1)
  }
  .btn-default.active {
    background-color: #1989fa;
    border-color: #1989fa;
    color: #fff;
  }
  .btn-default-fixed {
    width: 33.33%;
    padding: 0 4px;
    background-clip: content-box;
  }
  .filter-footer {
    text-align: right;
    padding: 10px;
  }
</style>
